<!--
   @desc 下拉选择字典控件，支持通过传入job、code、pid 等形式调用接口，自动生成下拉列表
   @author 石艳军
   @date 2022-03-30
   使用方式:
    <base-select-dictionary v-model="queryData.area" job="区" placeholder="所属区域"></base-select-dictionary>
-->
<template>
  <el-select
    v-model="selectValue"
    :class="{ block: block }"
    :placeholder="placeholderText"
    :clearable="clearable"
    :filterable="filterable"
    :filterMethod="filterMethod"
    :multiple="multiple"
    :collapse-tags="collapseTags"
    :disabled="disabled"
    :popper-class="popperClass"
    :size="size"
    @clear="onClear"
    @change="onChange">
    <el-option v-for="(item, idx) in optionList" :key="idx" :value="item[optionValueKey]" :label="item[optionLabel]"></el-option>
  </el-select>
</template>

<script>
import isArray from 'lodash/isArray';
import { dictionaryMap } from './dictionary';

export default {
  name: 'select-dictionary',
  model: {
    prop: 'value',
    event: 'change',
  },
  props: {
    value: null,
    code: null,
    // 父级id
    pid: null,
    // 字典名称
    job: {
      type: String,
      default: '',
    },
    block: {
      type: Boolean,
      default: false,
    },
    // 多选时是否将选中值按文字的形式展示
    collapseTags: {
      type: Boolean,
      default: false,
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false,
    },
    // 多选时用户最多可以选择的项目数，为 0 则不限制
    multipleLimit: {
      type: Number,
      default: 0,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    popperClass: {
      type: String,
    },
    size: {
      type: String,
      default: 'medium',  // medium | small | mini
    },
    clearable: {
      type: Boolean,
      default: true,
    },
    filterable: {
      type: Boolean,
      default: false,
    },
    filterMethod: {
      type: Function,
    },
    placeholder: {
      type: String,
      default: '',
    },
    // 设置第一个的选项
    unshiftItem: {
      type: String,
      default: '',
    },
    optionValue: {
      type: String,
      default: '',
    },
    optionLabel: {
      type: String,
      default: 'name',
    },
  },
  data() {
    return {
      selectValue: null,
      optionList: [],
      optionValueKey: 'code',
    };
  },
  computed: {
    placeholderText() {
      return this.placeholder ? this.placeholder : `请选择${this.job}`;
    },
  },
  watch: {
    value: {
      handler(newVal) {
        this.selectValue = newVal;
      },
      immediate: true,
      deep: true,
    },
    optionValue: {
      handler(newVal) {
        if (newVal) {
          this.optionValueKey = newVal;
        }
      },
      immediate: true,
    },
    pid: {
      handler(val) {
        // 每次 parentId 更改时，需要将 optionList 清空，重新获取数据，如果传入为空值，则直接将数组清空
        this.optionList = [];
        if (val) {
          this._handleDictionary(this.job);
        }
      },
      immediate: true,
    },
    job: {
      handler(val) {
        this._handleDictionary(val);
      },
      immediate: true,
    },
  },
  methods: {
    /**
     * 清除
     */
    onClear() {
      this.$emit('clear');
    },

    /**
     * 选择回调
     */
    onChange(val) {
      this.selectValue = val;
      // this.$emit('update.sync', val);
      this.$emit('change', val);
      if (isArray(val)) {
        this.$emit('selectItem', this.optionList.filter(d => val.some(i => d[this.optionValueKey] === i)));
      } else {
        this.$emit('selectItem', this.optionList.find(d => d[this.optionValueKey] === val));
      }
    },

    /**
     * 根据传入的 job 值，匹配对应的字典表数据
     * @param job
     * @private
     */
    _handleDictionary(job) {
      let action = null;

      if (job) {
        if (dictionaryMap.has(job)) {
          // type: dictionary code ; fn: normal
          action = { type: dictionaryMap.get(job), fn: 'normal' };
        } else {
          switch (job) {
            // type: 通过父级id获取下拉框子级数据 ; fn: pid
            case '所属类别':
              action = { type: this.pid, fn: 'pid' };
              break;

            // type: store 类型判断 ; fn: all
            case '省':
            case '市':
            case '区':
              action = { type: 'province_city_district', fn: 'all' };
              break;
            case '是否':
              action = { type: 'isOrNot', fn: 'all' };
              break;
          }
        }
      }

      if (this.code) {
        action = { type: this.code, fn: 'normal' };
      } else if (this.pid) {
        action = { type: this.pid, fn: 'pid' };
      }
      if (action) {
        if (action.fn === 'normal') {
          // 普通字典下拉
          this.$store.dispatch('dictionary/getDropdownBox', action.type).then(list => {
            // 监测设备类型 - 仅获取排水相关监测设备
            if (action.type === 'jcsb') {
              this.optionList = list.filter(o => o.systemFlag && o.systemFlag.includes('drain'));
            } else if (action.type === 'drain_riskReport_status') {
              // TODO: [风险评估报告状态] 由于发送功能暂时没做，所以此处的已发送状态需要过滤了
              this.optionList = list.filter(o => o.name !== '已发送');
            } else {
              this.optionList = list;
            }
            if (this.unshiftItem && this.optionList.some(d => d[this.optionLabel] !== this.unshiftItem)) {
              this.optionList.unshift({ [this.optionValueKey]: '', [this.optionLabel]: this.unshiftItem });
            }
          });
        } else if (action.fn === 'pid') {
          // 根据pid查询字典
          const pidParams = isArray(action.type) ? action.type.join(',') : action.type;
          this.$store.dispatch('dictionary/getDropDownBoxByParentId', pidParams).then(list => {
            this.optionList = list;
            if (this.unshiftItem && this.optionList.some(d => d[this.optionLabel] !== this.unshiftItem)) {
              this.optionList.unshift({ [this.optionValueKey]: '', [this.optionLabel]: this.unshiftItem });
            }
          });
        } else if (action.fn === 'all') {
          // 直接查询指定的所有字典下拉列表，如：省市区
          this.$store.dispatch('dictionary/getAllList', action.type).then(provinces => {
            // 省市区字典下拉列表
            if (action.type === 'province_city_district') {
              if (job === '省') {
                this.optionList = provinces;
              } else if (job === '市' || job === '区') {
                const defaultProvinceItem = provinces.find(o => o.code.toString() === this.$store.state.dictionary.provinceCode);
                if (defaultProvinceItem) {
                  this.$store.dispatch('dictionary/getDropDownBoxByParentId', defaultProvinceItem.code).then(cities => {
                    if (job === '市') {
                      this.optionList = cities.children;
                    } else if (job === '区') {
                      const defaultCityItem = cities.children.find(o => o.code.toString() === this.$store.state.dictionary.cityCode);
                      if (defaultCityItem) {
                        this.$store.dispatch('dictionary/getDropDownBoxByParentId', defaultCityItem.code).then(districts => {
                          this.optionList = districts.children;
                        });
                      }
                    }
                  });
                }
              }
            } else {
              this.optionList = provinces;
              if (this.unshiftItem && this.optionList.some(d => d[this.optionLabel] !== this.unshiftItem)) {
                this.optionList.unshift({ [this.optionValueKey]: '', [this.optionLabel]: this.unshiftItem });
              }
            }
          });
        }
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.el-select {
  &.block {
    display: block;

    ::v-deep .el-input {
      .el-input__inner {
        max-width: 100% !important;
      }
    }
  }

  &.el-select--medium {
    ::v-deep .el-input--medium {
      .el-input__suffix {
        height: 36px;
      }
    }
  }
}
</style>

<style lang="scss">
.el-select-dropdown {
  .el-scrollbar__wrap {
    overflow-x: hidden;
  }
}
</style>
